<template>
    <div class="table-warp">
        <el-table
            ref="multipleTableRef"
            style="width: 100%"
            :data="tableData"
            :row-key="rowKey"
            :highlight-current-row="isOneClick"
            :height="tableJson.tableHeight"
            :tree-props="treeProps"
            @selection-change="handleSelectionChange"
            @sort-change="changeSort"
            @select="select"
            @select-all="selectAll"
            @row-click="rowClick"
            @cell-click="cellClick"
        >
            <!-- 多选 -->
            <el-table-column
                v-if="tableJson.hasSelection"
                type="selection"
                width="55"
                :selectable="handleSelectable"
            />

            <template
                v-for="(item, index) in tableJson.tableFrom"
                :key="index"
            >
                <el-table-column
                    :width="item.width || ''"
                    :min-width="item.minWidth || ''"
                    :property="item.prop"
                    :label="item.label"
                    :sortable="item.sortable"
                    :fixed="item.fixed || false"
                    :show-overflow-tooltip="item.showOverflowTooltip"
                >
                    <!-- 自定义表头 -->
                    <template
                        v-if="item.type == 'isCustomHeader'"
                        #header
                    >
                        <div
                            v-if="item.tooltipHeader"
                            class="custom-tooltip"
                        >
                            <span class="title">{{ item.label }}</span>
                            <el-tooltip
                                class="box-item"
                                effect="light"
                                :content="item.msg"
                                placement="top"
                            >
                                <el-icon
                                    color="#c9cdd4"
                                    style="cursor: pointer"
                                >
                                    <QuestionFilled />
                                </el-icon>
                            </el-tooltip>
                        </div>
                    </template>
                    <template #default="scope">
                        <!-- 插槽 -->
                        <slot
                            v-if="item.type == 'slot'"
                            :name="item.slotName"
                            :scope="scope.row"
                            :index="scope.$index"
                        />
                        <!-- 字典 -->
                        <div
                            v-if="item.type == 'dict'"
                        >
                            {{ getDict(scope.row, item) }}
                        </div>
                        <!-- 有颜色状态 -->
                        <div v-if="item.type == 'tag'">
                            <el-tag
                                v-if="getDict(scope.row, item)"
                                :type="getCellType(scope.row, item)"
                                :effect="item.effect || 'dark'"
                                disable-transitions
                            >
                                {{ getDict(scope.row, item) }}
                            </el-tag>
                            <span v-else>-</span>
                        </div>
                        <!-- 文本 -->
                        <span
                            v-if="item.type == 'text'"
                        >
                            {{ scope.row[item.prop] || '-' }}
                        </span>
                        <!-- 解析富文本 -->
                        <div
                            v-if="item.type == 'html'"
                            v-html="scope.row[item.prop]"
                        />
                    </template>
                </el-table-column>
            </template>

            <el-table-column
                v-if="tableJson.operate"
                :fixed="tableJson.operateFixed"
                :label="tableJson.operateTitle || '操作'"
                :width="tableJson.operateWidth || ''"
            >
                <template #default="scope">
                    <div
                        v-if="islastLeve(scope.row)"
                        @click.stop
                    >
                        <template
                            v-for="(item, index) in tableJson.operate"
                            :key="index"
                        >
                            <!-- 浮窗操作 -->
                            <el-popover
                                v-if="item.type === 'popover'"
                                trigger="hover"
                            >
                                <template #reference>
                                    <el-button
                                        v-if="hidelClass(item, scope.row)"
                                        :disabled="banOperate(item, scope.row)"
                                        :type="item.buttonType || 'primary'"
                                        link
                                        @click="handleScope(scope.row, item)"
                                    >
                                        {{ changeButText(scope.row, item) }}
                                    </el-button>
                                </template>
                                <slot
                                    name="morePopover"
                                    :scope="scope.row"
                                >
                                    <template
                                        v-for="(p, i) in item.buttonList"
                                        :key="i"
                                    >
                                        <el-button
                                            v-if="hidelClass(item, scope.row)"
                                            :disabled="banOperate(item, scope.row)"
                                            :type="item.buttonType || 'primary'"
                                            link
                                            style="width:100%"
                                            @click="handleScope(scope.row, item)"
                                        >
                                            {{ changeButText(scope.row, item) }}
                                        </el-button>
                                    </template>
                                </slot>
                            </el-popover>
                            <template v-else>
                                <el-button
                                    v-if="hidelClass(item, scope.row)"
                                    :disabled="banOperate(item, scope.row)"
                                    :type="item.buttonType || 'primary'"
                                    link
                                    @click="handleScope(scope.row, item)"
                                >
                                    {{ changeButText(scope.row, item) }}
                                </el-button>
                            </template>
                        </template>
                    </div>
                </template>
            </el-table-column>

            <template #empty>
                <img src="@/assets/images/nolist.png">
                <p
                    v-if="isShowMsg"
                    class="empty-msg"
                >
                    {{ msg }}
                </p>
            </template>
        </el-table>
    </div>
</template>

<script setup name="tableModule">
import { reactive, toRefs, onMounted } from 'vue'
const props = defineProps({
    tableJson: {
        type: Object,
        default: () => ({})
    },
    tableData: {
        type: Array,
        default: () => []
    },
    rowKey: {
        type: String,
        default: 'id'
    },
    //单选
    isRadio: {
        type: Boolean,
        default: false
    },
    isOneClick: {
        type: Boolean,
        default: false
    },
    treeProps: {
        type: Object,
        default: () => ({ children: 'children' })
    },
    operateStatus: {
        type: Number,
        default: 1
    },
    isShowMsg: {
        type: Boolean,
        default: false
    },
    msg: {
        type: String,
        default: '暂无数据'
    },
    //禁止选中id
    selectableIds: {
        type: Array,
        default: () => []
    }
})
const emit = defineEmits(['selectTable', 'handleCb', 'changeSort', 'select', 'selectAll', 'rowClick', 'cellClick'])
const state = reactive({
    multipleTableRef: null,
    multipleSelection: [],
    toggleCheck: 'block'
})
onMounted(() => {
    state.toggleCheck = props.isRadio ? 'none' : 'block'
})
//隐藏操作
const hidelClass = (item, row) => {
    let isShow = true
    if (item.hidelType) {
        Object.keys(item.hidelType).forEach((k) => {
            if (row[k] === item.hidelType[k]) {
                isShow = false
            }
        })
    }
    return isShow
}
//禁止操作
const banOperate = (item, row) => {
    let isOperate = false
    if (item.banType) {
        Object.keys(item.banType).forEach((k) => {
            if (row[k] === item.banType[k]) {
                isOperate = true
            }
        })
    }
    return isOperate
}

const islastLeve = (row) => {
    if (props.operateStatus === 1) {
        return true
    }
    //父级不显示操作
    if (props.operateStatus === 2) {
        const child = props.treeProps.children
        return row[child] === undefined || (row[child] && row[child].length === 0)
    }
}
// 选择
const handleSelectionChange = (val) => {
    state.multipleSelection = val
    emit('selectTable', state.multipleSelection)
}
//操作文字
const changeButText = (row, item) => {
    if (item.statusList) {
        const bText = item.statusList.find((i) => i.type == row[item.prop])
        return bText.text
    }
    return item.text
}
// 操作
const handleScope = (row, item) => {
    const params = {
        callbackName: item.emit
    }
    if (item.statusList) {
        const bText = item.statusList.find((i) => i.type == row[item.prop])
        Object.assign(params, bText)
    }
    emit('handleCb', { row, ...params })
}
//排序
const changeSort = (e) => {
    if (e.order === 'ascending') {
        e.sortKey = 'asc'
    } else if (e.order === 'descending') {
        e.sortKey = 'desc'
    } else {
        e.sortKey = ''
        e.prop = ''
    }
    emit('changeSort', e)
}
//单击
const rowClick = (e) => {
    //单击不复选
    if (props.isOneClick) {
        emit('rowClick', e)
        return
    }
    //单选
    if (props.isRadio) {
        state.multipleTableRef.clearSelection()
        state.multipleTableRef.toggleRowSelection(e, true)
        emit('rowClick', [e])
    } else {
        //禁止选中
        if(props.selectableIds && props.selectableIds.length) {
            const checkItem = props.selectableIds.findIndex(id => id === e.id)
            if(checkItem > -1) {
                state.multipleTableRef.toggleRowSelection(e, false)
            } else {
                state.multipleTableRef.toggleRowSelection(e)
                emit('rowClick', e)
            }
        } else {
            props.tableJson.hasSelection && state.multipleTableRef.toggleRowSelection(e)
            emit('rowClick', e)
        }
    }
}
//手动勾选
const select = (e, row) => {
    //单选
    if (props.isRadio) {
        state.multipleTableRef.clearSelection()
        state.multipleTableRef.toggleRowSelection(row, true)
        emit('select', [row])
    } else {
        emit('select', e)
    }
}
//手动勾选全选
const selectAll = (e) => {
    emit('selectAll', e)
}
//单元格单击
const cellClick = (item, cell) => {
    emit('cellClick', item, cell)
}
const { multipleTableRef, toggleCheck } = toRefs(state)

//获取字典
const getDict = (row, item) => {
    if(item.dictList) {
        const dictContent = item.dictList.find((i) => i.value == row[item.prop])
        return dictContent.text
    } else {
        return row[item.prop]
    }
}
//获取tag状态
const getCellType = (row, item) => {
    return item.cellType ? item.cellType[row[item.prop]] : ''
}
//禁止选中
const handleSelectable = (row) => {
    if(props.selectableIds && props.selectableIds.length) {
        const checkItem = props.selectableIds.findIndex(id => id === row.id)
        return checkItem > -1 ? false : true
    }
    return true
}
defineExpose({
    multipleTableRef
})
</script>

<style lang="scss" scoped>
.table-warp{
    :deep(.el-table) {
        tr{
            height: 50px;
        }
        thead{
            tr{
            background: $main_bg_color;
                th{
                    @extend tr;
                    @include font();
                    .cell{
                        .el-checkbox{
                            display: v-bind(toggleCheck);
                        }
                    }
                }
            }
        }
        .el-table__row{
            td{
                @include font(14px, $fs-color);
                .column-span{
                    display: inline-block;
                    max-width: 100%;
                }
                .ellipsis{
                    @include ellipsis;
                }
            }
        }
        .el-table__empty-text{
            overflow: hidden;
            img{
                display: block;
                @include wh(250px,207px);
                margin: 40px auto;
            }
        }
    }
}
</style>
